package com.mingyuean.demo.mybatis.session;


import com.mingyuean.demo.mybatis.TypeAliasRegistry;
import com.mingyuean.demo.mybatis.binding.MapperRegistry;
import com.mingyuean.demo.mybatis.datasource.druid.DruidDataSourceFactory;
import com.mingyuean.demo.mybatis.mapping.Environment;
import com.mingyuean.demo.mybatis.mapping.MappedStatement;
import com.mingyuean.demo.mybatis.transaction.jdbc.JdbcTransactionFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @author MingYueAn
 * <p>  全局配置类：存放核心配置文件解析出来的内容
 * <p>  2023/3/17 2:02
 * @version: 1.0
 */
public class Configuration {

    /**
     * 环境
     */
    protected Environment environment;
    /**
     * 映射注册机，用于管理Mapper接口及其对应方法与SQL语句的映射
     */
    protected MapperRegistry mapperRegistry = new MapperRegistry(this);
    /**
     * 存储映射语句的Map，key为映射语句的ID，value为MappedStatement对象
     */
    protected final Map<String, MappedStatement> mappedStatementMap = new HashMap<>();
    /**
     * 类型别名注册机
     */
    protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();

    public Configuration() {
        // 注册类型别名
        typeAliasRegistry
                .registerAlias("JDBC", JdbcTransactionFactory.class)
                .registerAlias("DRUID", DruidDataSourceFactory.class);
    }

    /**
     * 添加指定包名下的所有Mapper接口及其对应方法与SQL语句的映射
     *
     * @param packageName 指定包名
     */
    public void addMappers(String packageName) {
        mapperRegistry.addMappers(packageName);
    }

    /**
     * 添加指定的Mapper接口及其对应方法与SQL语句的映射
     *
     * @param mapperClass Mapper接口的Class对象
     * @param <T>         Mapper接口类型
     */
    public <T> void addMapper(Class<T> mapperClass) {
        mapperRegistry.addMapper(mapperClass);
    }

    /**
     * 获取指定Mapper接口类型的代理对象，用于执行Mapper接口方法对应的SQL语句
     *
     * @param mapperClass Mapper接口的Class对象
     * @param sqlSession  Mapper接口的Class对象
     * @param <T>         Mapper接口类型
     * @return 指定Mapper接口类型的代理对象
     */
    public <T> T getMapper(Class<T> mapperClass, SqlSession sqlSession) {
        return mapperRegistry.getMapper(mapperClass, sqlSession);
    }

    /**
     * 判断是否存在指定的Mapper接口及其对应方法与SQL语句的映射
     *
     * @param mapperClass Mapper接口的Class对象
     * @return 如果存在指定的Mapper接口及其对应方法与SQL语句的映射则返回true，否则返回false
     */
    public boolean hasMapper(Class<?> mapperClass) {
        return mapperRegistry.hasMapper(mapperClass);
    }

    /**
     * 向Configuration对象中添加一个映射语句
     *
     * @param mappedStatement MappedStatement对象，表示一个映射语句的详细信息
     */
    public void addMappedStatement(MappedStatement mappedStatement) {
        mappedStatementMap.put(mappedStatement.getId(), mappedStatement);
    }

    /**
     * 根据映射语句的ID获取对应的MappedStatement对象
     *
     * @param id 映射语句的ID
     * @return 对应的MappedStatement对象，如果不存在则返回null
     */
    public MappedStatement getMappedStatement(String id) {
        return mappedStatementMap.get(id);
    }

    public TypeAliasRegistry getTypeAliasRegistry() {
        return typeAliasRegistry;
    }

    public Environment getEnvironment() {
        return environment;
    }

    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
